package com.pwr.app;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.util.Random;

import com.pwr.app.ui.WindowHelper;

public class Noise {

	public static double[][] imageSaltAndPeper(double[][] pixelsArray, double percentage) {
		int height = pixelsArray.length;
		int width = pixelsArray[0].length;

		int salt = (int) (height * width * percentage / 100);
		int pepper = (int) (height * width * percentage / 100);

		for (int i = 0; i < salt; i++) {
			int x = (int) (Math.random() * width);
			int y = (int) (Math.random() * height);
			pixelsArray[y][x] = -1;
		}

		for (int i = 0; i < pepper; i++) {
			int x = (int) (Math.random() * width);
			int y = (int) (Math.random() * height);
			pixelsArray[y][x] = 1;
		}
		return pixelsArray;
	}

	public static double[][] imageHover(double[][] pixelsArray, double percentage, Constants.Locations hoverArea) {
		int buffer = 0; // default for LEFT hoverArea
		boolean ifHorizontal = true; // default for LEFT hoverArea (and
										// Horizontal)
		if (hoverArea == Constants.Locations.BOTTOM || hoverArea == Constants.Locations.CENTER_VERTICAL || hoverArea == Constants.Locations.TOP)
			ifHorizontal = false;
		if (pixelsArray.length == 0)
			return null;
		int width = pixelsArray.length;
		int height = pixelsArray.length;
		int hoveredPixels = (int) ((width * percentage) / 100);

		if (hoverArea == Constants.Locations.CENTER_HORIZONTAL || hoverArea == Constants.Locations.CENTER_VERTICAL) {
			buffer = (int) (width - hoveredPixels) / 2;
		} else if (hoverArea == Constants.Locations.RIGHT || hoverArea == Constants.Locations.BOTTOM) {
			buffer = width - hoveredPixels;
		} else {
			buffer = 0;
		}

		if (ifHorizontal) {
			for (int i = 0; i < height; i++)
				for (int j = 0 + buffer; j < buffer + hoveredPixels; j++) {
					pixelsArray[i][j] = -1.0;
				}
			return pixelsArray;
		} else {
			for (int i = 0 + buffer; i < buffer + hoveredPixels; i++)
				for (int j = 0; j < height; j++) {
					pixelsArray[i][j] = -1.0;
				}
			return pixelsArray;
		}
	}

	public static double[][] imageShear(double[][] pixelsArray, double percentage) {
		percentage = percentage / 100;
		for (int y = 0; y < pixelsArray.length; y++) {
			if (y < pixelsArray.length / 2) {
				int k = (int) ((percentage * ((double) pixelsArray.length / (double) 2 - (double) y) / (double) pixelsArray.length) * (double) pixelsArray.length);
				for (int col = pixelsArray[0].length - 1; col > 0; col--) {
					if (col + k < pixelsArray[0].length)
						pixelsArray[y][col + k] = pixelsArray[y][col];
				}
				for (int i = 0; i < k + 1; i++) {
					pixelsArray[y][i] = -1;
				}
			} else {
				int k = (int) ((percentage * ((double) y - (double) pixelsArray.length / (double) 2) / (double) pixelsArray.length) * (double) pixelsArray.length);
				for (int col = 0; col < pixelsArray[0].length; col++) {
					if (col - k > 0)
						pixelsArray[y][col - k] = pixelsArray[y][col];
				}
				for (int i = pixelsArray[0].length - 1; i + k - 1 > pixelsArray[0].length; i--) {
					pixelsArray[y][i] = -1;
				}
			}
		}

		return pixelsArray;

	}

	public static double[][] imageRotation(double[][] pixelsArray, double angle) {
		int size = pixelsArray.length;
		BufferedImage img = WindowHelper.loadDoubleArrayIntoImage(pixelsArray);
		AffineTransform xform = new AffineTransform();
		xform.translate(0.5 * img.getHeight(), 0.5 * img.getWidth());
		xform.rotate(Math.toRadians(angle));
		xform.translate(-0.5 * img.getWidth(), -0.5 * img.getHeight());
		AffineTransformOp op = new AffineTransformOp(xform, AffineTransformOp.TYPE_BILINEAR);
		img = op.filter(img, null);
		double[][] temp = WindowHelper.loadImageIntoDoubleArrayInvert(img);
		for (int i = 0; i < pixelsArray.length; i++)
			for (int l = 0; l < pixelsArray[0].length; l++) {
				pixelsArray[i][l] = temp[i][l];
			}
		return pixelsArray;
	}
}